package com.ccteam.shared.domain.playlistsheet

import android.provider.MediaStore.UNKNOWN_STRING
import android.support.v4.media.MediaMetadataCompat
import com.ccteam.fluidmusic.fluidmusic.common.MusicServiceConnectionFlow
import com.ccteam.fluidmusic.fluidmusic.media.extensions.*
import com.ccteam.model.Resource
import com.ccteam.model.music.BITRATE_NO
import com.ccteam.model.music.MusicVO
import com.ccteam.model.playlistsheet.PLAYLIST_SHEET_TYPE_PUBLIC
import com.ccteam.model.playlistsheet.PlaylistSheetVO
import com.ccteam.network.ApiError
import com.ccteam.shared.core.UserCore
import com.ccteam.shared.data.playlistsheet.PlaylistSheetRepository
import com.ccteam.shared.domain.FlowUseCase
import com.ccteam.shared.result.artist.ArtistInfoData
import com.ccteam.shared.result.playlistsheet.PlaylistSheetDetailHeaderItem
import com.ccteam.shared.result.playlistsheet.PlaylistSheetMusicItem
import com.ccteam.shared.utils.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.zip
import javax.inject.Inject

/**
 * @author Xiaoc
 * @since 2021/3/16
 *
 * 歌单详情内容获取Domain层
 */
class PlaylistSheetDetailDataUseCase @Inject constructor(
    private val musicServiceConnectionFlow: MusicServiceConnectionFlow,
    private val playlistSheetRepository: PlaylistSheetRepository,
    private val userCore: UserCore
): FlowUseCase<Pair<String, String>, PlaylistSheetDetailDataUseCase.PlaylistSheetDetailUseCaseResult>(Dispatchers.IO) {


    override fun execute(parameters: Pair<String, String>): Flow<Resource<PlaylistSheetDetailUseCaseResult>> {
        val (parentId,playlistId) = parameters
        // 如果登录则带上Token去访问歌单详情，以便隐私歌单能够访问到
        val token = if(userCore.isLogin.value){
            userCore.userInfo.value.userToken
        } else {
            null
        }
        return playlistSheetRepository.getPlaylistInfo(playlistId,token).zip(
            playlistSheetRepository.getPlaylistMusicList(playlistId,token)
        ){ sheetInfo, sheetMusicList ->
            if(sheetInfo is Resource.Success && sheetMusicList is Resource.Success){
                val result = transformToResult(parentId,sheetInfo.data?.data,sheetMusicList.data?.data)
                if(result != null){
                    Resource.Success(result)
                } else {
                    Resource.Error(
                        ApiError.dataIsNullCode, "数据为空不正确",
                        null)
                }
            } else if(sheetInfo is Resource.Error || sheetMusicList is Resource.Error){
                // 如果请求来的数据有一项为空不存在，则Error数据直接为null，让界面直接显示错误信息
                Resource.Error(ApiError.serverErrorCode,sheetInfo.message ?: sheetMusicList.message ?: "未知错误",
                    transformToResult(parentId,sheetInfo.data?.data,sheetMusicList.data?.data))
            } else {
                Resource.Loading(transformToResult(parentId,sheetInfo.data?.data,sheetMusicList.data?.data))
            }

        }
    }

    private fun transformToResult(
        parentId: String,
        sheetInfo: PlaylistSheetVO?,
        sheetMusicList: List<MusicVO>?
    ): PlaylistSheetDetailUseCaseResult?{
        if(sheetInfo == null){
            return null
        }
        val header = transformHeader(sheetInfo)
        val musicList = transformMusicList(parentId,sheetMusicList ?: emptyList(),header.userId)

        return PlaylistSheetDetailUseCaseResult(header,musicList)
    }

    private fun transformHeader(sheetInfo: PlaylistSheetVO): PlaylistSheetDetailHeaderItem {
        val userInfo = userCore.userInfo.value
        val shouldShowEditContent = userCore.isLogin.value

        // 展示添加按钮的条件是 必须处于登录状态且当前歌单是共享的或者当前用户与歌单拥有者相同
        val showAddContent = shouldShowEditContent
                && (sheetInfo.type == PLAYLIST_SHEET_TYPE_PUBLIC || sheetInfo.userId == userInfo.userId)

        // 展示编辑和删除按钮的条件是 必须处于登录状态且当前用户与歌单拥有者相同
        val showEditDeleteContent = shouldShowEditContent
                && sheetInfo.userId == userInfo.userId

        return PlaylistSheetDetailHeaderItem(sheetInfo.id,sheetInfo.playlistName,
            sheetInfo.imgUrl + PHOTO_QUALITY,
            sheetInfo.userId ?: EMPTY_STRING, sheetInfo.userImage + PHOTO_QUALITY,
            sheetInfo.userName ?: UNKNOWN_STRING,sheetInfo.introduction ?: EMPTY_STRING,sheetInfo.type,
            showAddContent,showEditDeleteContent,showEditDeleteContent)
    }

    private fun transformMusicList(parentId: String,
                                   sheetMusicList: List<MusicVO>,
                                   hostUserId: String): List<PlaylistSheetMusicItem>{
        /**
         * 将音乐信息加入到browseTree中以便播放
         */
        val items = mutableListOf<MediaMetadataCompat>()
        sheetMusicList.forEach { music ->
            if(music.maxBitrate == BITRATE_NO || music.url.isNullOrEmpty()){
                return@forEach
            }
            items.add(
                MediaMetadataCompat.Builder().apply {
                    id = music.id
                    duration = music.duration
                    title = music.name
                    displayTitle = music.name
                    album = music.albumName
                    displaySubtitle = music.albumName
                    displayDescription = music.artists
                    artist = music.artists
                    albumId = music.albumId
                    trackNumber = music.track.toLong()
                    mediaUri = music.url
                    albumArtUri = music.imgUrl + ALBUM_QUALITY
                    displayIconUri = music.imgUrl + ALBUM_QUALITY
                }.build()
            )
        }
        musicServiceConnectionFlow.addOnlineMusicItems(
            parentId = parentId,
            items = items
        )

        val userInfo = userCore.userInfo.value

        return sheetMusicList.map {
            /**
             * 分割成ArtistInfoData类型，其中含有歌手信息
             */
            val artistsArray = it.artists.split(ARTIST_SEPARATOR)
            val artistInfo = if(artistsArray.size == it.artistsId.size){
                artistsArray.mapIndexed{ index, artistName ->
                    ArtistInfoData(it.artistsId[index],artistName)
                }
            } else {
                emptyList()
            }
            PlaylistSheetMusicItem(it.playlistSongId ?: EMPTY_STRING,
                it.id,it.name,it.artists,artistInfo, it.albumId,
                it.imgUrl + ALBUM_QUALITY,it.maxBitrate,
                playable = !it.url.isNullOrEmpty(),
                musicServiceConnectionFlow.nowPlaying.value.getPlaybackStatus(it.id),
                /* 如果当前歌曲内容所属的userId为当前登录者，或者说当前歌曲所在歌单的userId为当前登陆者，均可进行删除歌曲权限操作 */
                it.userId == userInfo.userId || userInfo.userId == hostUserId)
        }
    }

    data class PlaylistSheetDetailUseCaseResult(
        val playlistSheetHeader: PlaylistSheetDetailHeaderItem,
        val playlistSheetMusicList: List<PlaylistSheetMusicItem>
    )
}